package BeenChina.PM.Action;

 
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat; 
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import net.sf.json.JSONArray;

import BeenChina.PM.Model.ModelCaseCostBasicInfo;
import BeenChina.PM.Model.ModelCaseCostExchangeRateInfo;
import BeenChina.PM.Model.ModelCaseCostGeneralSurvey; 
import BeenChina.PM.Model.ModelUser;
import BeenChina.PM.Service.ServiceFactory;
import BeenChina.PM.Util.EncodeDownLoadFileName;
import BeenChina.PM.Util.ExportInfo;
import BeenChina.PM.Util.ExportToExcel;
import BeenChina.PM.Util.StringUtil; 
import BeenChina.PM.Util.xmlSerializer;
 
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class CaseCostQueryAction extends ActionSupport {

 
	private static final long serialVersionUID = 1L;
	private String dateFrom,dateTo,currency;
	private Map<String, Object> tableData;  
	private InputStream excelStream;  
	private String fileName;
	private static String EXPORTID = "471";
	private boolean exportExcel; 
	private static final Log log = LogFactory.getLog(CaseCostQueryAction.class);
	
	public String getCurrencyUnit() {
		return currency.equals("rmb")? "元":"円";
	}
	
	public String getCurrency() {
		return currency.equals("rmb")? "人民元":"日本円";
	}

	public void setCurrency(String currency) {
		this.currency = currency;
	}

	public boolean isExportExcel() {
		return exportExcel;
	} 
	
	public InputStream getExcelStream() {
		return excelStream;
	}

	public void setExcelStream(InputStream excelStream) {
		this.excelStream = excelStream;
	}

	public String getFileName() throws UnsupportedEncodingException {		
		ServletActionContext.getResponse().setHeader("charset","UTF-8");
		fileName = EncodeDownLoadFileName.encode(ServletActionContext.getRequest(), fileName); 
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	
	public void setDateFrom(String dateFrom) {
		this.dateFrom = dateFrom;
	} 

	public Map<String, Object> getTableData() {
		return tableData;
	}
  
	public void setDateTo(String dateTo) {
		this.dateTo = dateTo;
	}
	
	@Override
	public String execute()	{
		ModelUser user = (ModelUser) ActionContext.getContext().getSession().get("user");
		if (user!=null)
		  exportExcel = user.concatPermission(EXPORTID);
  		return "load";
	}
	
	
	public List<ModelCaseCostGeneralSurvey> getGeneralSurvey()	throws Exception {
		try{
			//System.out.print(currency);
			//System.out.print(getCurrency());
			 if (StringUtil.isDate(dateFrom,"yyyy-MM") &&   StringUtil.isDate(dateTo,"yyyy-MM")  ){
				return   ServiceFactory.getInstance().getCaseProductionInfoService().selectCaseCostGeneralSurvey(dateFrom, dateTo,getCurrency())	;			 				
			 }
			 else {
				 return null;
			}
		 }
		 catch(Exception exp){
			 throw exp;
		 }
	}
	
	public List<ModelCaseCostBasicInfo> getBasicInfo()	throws Exception {
		try{
			 if (StringUtil.isDate(dateFrom,"yyyy-MM") &&   StringUtil.isDate(dateTo,"yyyy-MM")  ){
				return   ServiceFactory.getInstance().getCaseProductionInfoService().selectCaseCostBasicInfo(dateFrom, dateTo,getCurrency())	;			 				
			 }
			 else {
				 return null;
			}
		 }
		 catch(Exception exp){
			 throw exp;
		 }
	}
	
	public List<ModelCaseCostExchangeRateInfo> getExchangeRateInfo()	throws Exception {
		try{
			 if (StringUtil.isDate(dateFrom,"yyyy-MM") &&   StringUtil.isDate(dateTo,"yyyy-MM")  ){
				return   ServiceFactory.getInstance().getCaseProductionInfoService().selectCaseCostExchangeRateInfo(dateFrom, dateTo,getCurrency())	;			 				
			 }
			 else {
				 return null;
			}
		 }
		 catch(Exception exp){
			 throw exp;
		 }
	}
	
	 public String refreshData() throws Exception
	 {  		
		 List<ModelCaseCostGeneralSurvey> costGeneralSurveys = getGeneralSurvey();
		 List<ModelCaseCostBasicInfo> costBasicInfos = getBasicInfo();
		 List<ModelCaseCostExchangeRateInfo> exchangeRateInfos = getExchangeRateInfo();
		 
		 Map<String, Object> map = new HashMap<String, Object>();   
		 
		 map.put("BasicInfoTableA", getBasicInfoTableA(costBasicInfos));
		 map.put("BasicInfoTableB", getBasicInfoTableB(costBasicInfos));
		 map.put("BasicInfoTableC", getBasicInfoTableC(costBasicInfos));		 
		 map.put("GeneralSurvey", getGeneralSurveyTable(costGeneralSurveys));
		 
		 map.put("ExchangeRate", getExchangeRateInfoTable(exchangeRateInfos)); 
	 
		 tableData = map;
	     return ActionSupport.SUCCESS;  
	 }

	 
	private JSONArray getExchangeRateInfoTable(
			List<ModelCaseCostExchangeRateInfo> list) {
		 JSONArray json = new JSONArray();	
		 JSONArray map = new JSONArray(); 
		 if (list ==null || list.size() ==0)
		 {
			 return map;
		 }
			
		 Map<String, JSONArray> detail = new  HashMap<String, JSONArray>();

	
		 
		 json = new JSONArray(); json.add("内容");	detail.put("Date", json );
		 json = new JSONArray(); json.add("【1人民元両替日本円】");	 	detail.put("ExchangeRate", json );
		
		 for (int i = 0; i < list.size(); i++) {
			 ModelCaseCostExchangeRateInfo model = list.get(i); 
		     
		 
			 detail.get("Date").add(model.getDate());
			 detail.get("ExchangeRate").add(model.getExchangeRate());
		 }
		 
		 map.add(detail.get("Date")); 
		 map.add(detail.get("ExchangeRate") );
		 
		// TODO Auto-generated method stub
		return map;
	}

	private JSONArray getBasicInfoTableA(
			List<ModelCaseCostBasicInfo> list) {
		
		JSONArray map = new JSONArray(); 
		 if (list ==null || list.size() ==0)
		 {
			 return map;
		 }
		 
		 JSONArray json = new JSONArray();
		 json.add("級別");
		 json.add("基礎給料(元/人)"); 
		 json.add("1秒当り入力原価");
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("超級");
		 json.add(getBaseinfoValue("SuperMoney",list));
		 json.add(getBaseinfoValue("SuperSPrice",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("高級");
		 json.add(getBaseinfoValue("SeniorMoney",list));
		 json.add(getBaseinfoValue("SeniorSPrice",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("1級");
		 json.add(getBaseinfoValue("L1Money",list));
		 json.add(getBaseinfoValue("L1SPrice",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("2級");
		 json.add(getBaseinfoValue("L2Money",list));
		 json.add(getBaseinfoValue("L2SPrice",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("3級");
		 json.add(getBaseinfoValue("L3Money",list));
		 json.add(getBaseinfoValue("L3SPrice",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("4級");
		 json.add(getBaseinfoValue("L4Money",list));
		 json.add(getBaseinfoValue("L4SPrice",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("5級");
		 json.add(getBaseinfoValue("L5Money",list));
		 json.add(getBaseinfoValue("L5SPrice",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("平均");
		 json.add("");
		 json.add(getBaseinfoValue("AvgSPrice",list)); 
		 map.add(json);
		 
		 
		 return map;
	}

	private JSONArray getBasicInfoTableB(
			List<ModelCaseCostBasicInfo> list) {
		
		JSONArray map = new JSONArray(); 
		 if (list ==null || list.size() ==0)
		 {
			 return map;
		 }
		 
		 JSONArray json = new JSONArray();
		 json.add("予想満負荷稼働率");
		 json.add(""); 
		 json.add("");
		 map.add(json);
		 
		 json = new JSONArray();
		 
		 json.add("平均月予定出勤日数");	 
		 json.add("");
		 json.add(getBaseinfoValue("AvgWorkDay",list));
		 map.add(json);
		 
		 json = new JSONArray();		 
		 json.add("出勤時間(1人)	");
		 json.add("");
		 json.add(getBaseinfoValue("DayWorkTime",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("避けられない入力外活動");
		 json.add("水飲み、トイレ");
		 json.add(getBaseinfoValue("NonWorkTime1",list));
		 map.add(json);
		 
		 json = new JSONArray();		 
		 json.add("");
		 json.add("入力外操作");
		 json.add(getBaseinfoValue("NonWorkTime2",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("");
		 json.add("FB或は育成");
		 json.add(getBaseinfoValue("NonWorkTime3",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("予想満負荷稼働率");
		 json.add("");
		 json.add(getBaseinfoValue("FullUtiliza",list));
		 map.add(json); 
		 
		 return map;
	}
	
	private JSONArray getBasicInfoTableC(
			List<ModelCaseCostBasicInfo> list) {
		
		JSONArray map = new JSONArray(); 
		 if (list ==null || list.size() ==0)
		 {
			 return map;
		 }
		 
		 JSONArray json = new JSONArray();
		 json.add("その他支払料(毎月支払)");
		 json.add(""); 
		 json.add("");
		 map.add(json);
		 
		 json = new JSONArray();		 
		 json.add("減価償却（"+getCurrencyUnit()+"/台）");	 
		 json.add("サーバ");
		 json.add(getBaseinfoValue("ServersMoney",list));
		 map.add(json);
		 
		 json = new JSONArray();		 
		 json.add("福利厚生（支払比率)	");
		 json.add("福利厚生");
		 json.add(getBaseinfoValue("InsuranceRate",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("福利手当て("+getCurrencyUnit()+"/人)");
		 json.add("交通手当て");
		 json.add(getBaseinfoValue("Allowance1",list));
		 map.add(json);
		 
		 json = new JSONArray();		 
		 json.add("");
		 json.add("食事手当て");
		 json.add(getBaseinfoValue("Allowance2",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("");
		 json.add("人事管理費");
		 json.add(getBaseinfoValue("Allowance3",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("");
		 json.add("大額手当て");
		 json.add(getBaseinfoValue("Allowance4",list));
		 map.add(json); 
		 
		 json = new JSONArray();
		 json.add("その他("+getCurrencyUnit()+"/人)");
		 json.add("間接価格");
		 json.add(getBaseinfoValue("OtherCost1",list));
		 map.add(json);
		 
		 json = new JSONArray();
		 json.add("");
		 json.add("割り掛け");
		 json.add(getBaseinfoValue("OtherCost2",list));
		 map.add(json);
		 return map;
	}
	
	private String getBaseinfoValue(String key,List<ModelCaseCostBasicInfo> list)
	{
		 if (list ==null || list.size() ==0)
		 {
			 return "";
		 }
		 String valueString = "";
		 
		 for (ModelCaseCostBasicInfo model : list) {
			if (model.getCategoryName().equals(key)){
			
				valueString = model.getCategoryInfo();
			}
		}
		 
		 return valueString;
	}
	
	private JSONArray getGeneralSurveyTable(
			List<ModelCaseCostGeneralSurvey> list) {
		 JSONArray json = new JSONArray();	
		 
		 JSONArray mapGeneralSurvey = new JSONArray(); 
		 if (list ==null || list.size() ==0)
		 {
			 return mapGeneralSurvey;
		 }
		 
		 DecimalFormat df = new DecimalFormat("#.0");
		 DecimalFormat df0 = new DecimalFormat("#");
		
		 Map<String, JSONArray> detail = new  HashMap<String, JSONArray>();

		 
		 json = new JSONArray(); json.add("リソース情報"); json.add("在職人数");	 json.add("合計");	detail.put("EmpTotal", json );
		 json = new JSONArray(); json.add("(人+機械)");	json.add("予定合計出勤"); json.add("時間");	detail.put("EWorkTime", json );
		 json = new JSONArray(); json.add("");	json.add("実際総出勤");	 json.add("時間");	detail.put("WorkTime", json );
		 json = new JSONArray(); json.add("");	json.add("平日出勤");	 json.add("時間");	detail.put("WeekDayTime", json );
		 json = new JSONArray(); json.add("");	json.add("平日殘業(1.5倍)");json.add("時間");	detail.put("WeekDayOverTime", json );
		 json = new JSONArray(); json.add("");	json.add("土日殘業(2倍)");	json.add("時間");	detail.put("RestDayOverTime", json );		
		 json = new JSONArray(); json.add("");	json.add("CHN祝日殘業(3倍)");json.add("時間");	detail.put("HoliDayOverTime", json );
		 json = new JSONArray(); json.add("");	json.add("サーバ(物理)");	json.add("台");	  detail.put("ServersCount", json );
		 json = new JSONArray(); json.add("支出");	json.add("予定支出(OP)");json.add("万"+getCurrencyUnit()+""); detail.put("OPEPayment", json );
		 json = new JSONArray(); json.add("");	json.add("予定支出(瀋陽E)");	json.add("万"+getCurrencyUnit()+"");  detail.put("ECheckEPayment", json );
		 json = new JSONArray(); json.add("");	json.add("サーバ");	json.add("万"+getCurrencyUnit()+"");  			detail.put("ServersPayment", json );
		 json = new JSONArray(); json.add("");	json.add("福利厚生");	json.add("万"+getCurrencyUnit()+"");  		detail.put("InsurancePayment", json );
		 json = new JSONArray(); json.add("");	json.add("福利手当て");	json.add("万"+getCurrencyUnit()+""); 		 detail.put("AllowancePayment", json );
		 json = new JSONArray(); json.add("");	json.add("その他(間接価格)");json.add("万"+getCurrencyUnit()+""); 	 detail.put("OtherCost1", json );
		 json = new JSONArray(); json.add("");	json.add("その他(割り掛け)");json.add("万"+getCurrencyUnit()+""); 	 detail.put("OtherCost2", json ); 
		 json = new JSONArray(); json.add("");	json.add("合計");	json.add("万"+getCurrencyUnit()+"");			 detail.put("TotalPayment", json );
		 json = new JSONArray(); json.add("処理情報"); json.add("予定入力可能");	json.add("時間"); detail.put("EEntryTime", json );
		 json = new JSONArray(); json.add("");	json.add("実際処理合計");	json.add("時間");	 detail.put("EntryTime", json );
		 json = new JSONArray(); json.add("");	json.add("OPリソース利用率1");json.add("%");	 detail.put("OPUtiliza1", json );
		 json = new JSONArray(); json.add("");	json.add("OPリソース利用率2");json.add("%");	 detail.put("OPUtiliza2", json );     

		 
		 
		
		 /*tittle*/
		 JSONArray jsonTittle = new JSONArray();
		 jsonTittle.add("内容");
		 jsonTittle.add("類別"); 
		 jsonTittle.add("単位");
		 
		 for (int i = 0; i < list.size(); i++) {
			 ModelCaseCostGeneralSurvey model = list.get(i); 
		     
			 //add tittle
			 jsonTittle.add(model.getDate());
			 detail.get("EmpTotal").add(model.getEmpTotal());
			 detail.get("EWorkTime").add(df.format(model.getEworkTime()));
			 detail.get("WorkTime").add(df.format(model.getWorkTime()));
			 detail.get("WeekDayTime").add(df.format(model.getWeekDayTime()));
			 detail.get("WeekDayOverTime").add(df.format(model.getWeekDayOverTime()));
			 detail.get("RestDayOverTime").add(df.format(model.getRestDayOverTime()));			 
			 detail.get("HoliDayOverTime").add(df.format(model.getHoliDayOverTime()));
			 detail.get("ServersCount").add(df0.format(model.getServersCount()));
			 detail.get("OPEPayment").add(df.format(model.getOpePayment()));
			 detail.get("ECheckEPayment").add(df.format(model.getEcheckEPayment()));
			 detail.get("ServersPayment").add(df.format(model.getServersPayment()));
			 detail.get("InsurancePayment").add(df.format(model.getInsurancePayment()));
			 detail.get("AllowancePayment").add(df.format(model.getAllowancePayment()));
			 detail.get("OtherCost1").add(df.format(model.getOtherCost1()));
			 detail.get("OtherCost2").add(df.format(model.getOtherCost2()));
			 detail.get("TotalPayment").add(df.format(model.getTotalPayment()));
			 detail.get("EEntryTime").add(df.format(model.getEentryTime()));
			 detail.get("EntryTime").add(df.format(model.getEntryTime()));
			 detail.get("OPUtiliza1").add(model.getOpUtiliza1());
			 detail.get("OPUtiliza2").add(model.getOpUtiliza2());
			 
		}
		
		 mapGeneralSurvey.add(jsonTittle);   
		// mapGeneralSurvey.addAll(detail.values());   
		 mapGeneralSurvey.add(detail.get("EmpTotal")); 
		 mapGeneralSurvey.add(detail.get("EWorkTime") );
		 mapGeneralSurvey.add(detail.get("WorkTime") );
		 mapGeneralSurvey.add(detail.get("WeekDayTime")); 
		 mapGeneralSurvey.add(detail.get("WeekDayOverTime")); 
		 mapGeneralSurvey.add(detail.get("RestDayOverTime"));
		 mapGeneralSurvey.add(detail.get("HoliDayOverTime") );
		 mapGeneralSurvey.add(detail.get("ServersCount") );
		 mapGeneralSurvey.add(detail.get("OPEPayment") );
		 mapGeneralSurvey.add(detail.get("ECheckEPayment")); 
		 mapGeneralSurvey.add(detail.get("ServersPayment") );
		 mapGeneralSurvey.add(detail.get("InsurancePayment") );
		 mapGeneralSurvey.add(detail.get("AllowancePayment") );
		 mapGeneralSurvey.add(detail.get("OtherCost1") );
		 mapGeneralSurvey.add(detail.get("OtherCost2") );
		 mapGeneralSurvey.add(detail.get("TotalPayment") );
		 mapGeneralSurvey.add(detail.get("EEntryTime") );
		 mapGeneralSurvey.add(detail.get("EntryTime") );
		 mapGeneralSurvey.add(detail.get("OPUtiliza1") );
		 mapGeneralSurvey.add(detail.get("OPUtiliza2") ); 
		 
		return mapGeneralSurvey;
	}
	
	public String export() throws Exception{		 
		try{	
			String file=ServletActionContext.getServletContext().getRealPath("WEB-INF/excel/CaseCostQuery.xls");
			
			 List<ModelCaseCostGeneralSurvey> costGeneralSurveys = getGeneralSurvey();
			 List<ModelCaseCostBasicInfo> costBasicInfos = getBasicInfo();
			 List<ModelCaseCostExchangeRateInfo> exchangeRateInfos = getExchangeRateInfo();
			 
			 Map<String, JSONArray> map = new HashMap<String, JSONArray>(); 
			 
			 map.put("基礎給料情報", getBasicInfoTableA(costBasicInfos));
			 map.put("予想満負荷稼働情報", getBasicInfoTableB(costBasicInfos));
			 map.put("その他支払情報", getBasicInfoTableC(costBasicInfos));		 
			 map.put("運用関連状況報告", getGeneralSurveyTable(costGeneralSurveys));		
			 
			 if (currency.equals("jpy")){				 
				 map.put("毎月為替レート情報", getExchangeRateInfoTable(exchangeRateInfos));
			 }
			
			ByteArrayOutputStream out = new ByteArrayOutputStream(); 		
			this.setFileName("案件コスト状況・一覧「" +getCurrency()+"」_"+ dateFrom + "~" + dateTo );			
			String infoFile=ServletActionContext.getServletContext().getRealPath("WEB-INF/excel/CaseCostQuery.xml");
			List<ExportInfo> infoList = (new xmlSerializer<List<ExportInfo>>()).read(infoFile);
			
			ExportToExcel.export(file, map, infoList,out);
			
			setExcelStream(new ByteArrayInputStream(out.toByteArray()));	   			   			      
			out.close();
		
			return ActionSupport.SUCCESS;
		}
		catch(Exception exp){
			log.error(exp);
			return ActionSupport.ERROR;
		}		
	}			
}
